/*
 * 
 * 
 * @author: Oren Zamir
 */
package org.valire.usermanagement.beans;

import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.jasypt.util.password.BasicPasswordEncryptor;
import org.valire.util.persistency.BaseEntity;


/**
 * The Class User.
 */
@Entity(name = "USERS")
@Table(name = "USERS")
public class User extends BaseEntity {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;

	/** The username. */
	@Column(name = "USER_NAME")
	private String userName;

	/** The firstname. */
	@Column(name = "FIRST_NAME")
	private String firstName;

	/** The lastname. */
	@Column(name = "LAST_NAME")
	private String lastName;

	/** The lastname. */
	@Column(name = "SAP_NAME")
	private String sapName;

	/** The lastname. */
	@Column(name = "SAP_LANGUAGE")
	private String sapLanguage;
	
	/** The password. */
	@Column(name = "PASSWORD")
	private String password;

	/** The enabled. */
	@Column(name = "ENABLED")
	private boolean enabled = false;

	/** The email address. */
	@Column(name = "EMAIL_ADDRESS")
	private String emailAddress;

	/** The expiration. */
	@Column(name = "CREDENTIALS_EXPIRATION")
	private Date credentialsNoneExpired = null;

	/** Is the account not locked. */
	@Column(name = "ACCOUNT_NONE_LOCKED")
	private boolean accountNonLocked = true;

	/** Is the account not expired. */
	@Column(name = "ACCOUNT_NONE_EXPIRED")
	private boolean accountNonExpired = false;

	/** Is the account not expired. */
	@Column(name = "CONFIGURATIONS")
	private String configurations = "{}";

	/** The roles. */
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "USERS_ROLES", joinColumns = { @JoinColumn(name = "USERS_ID") }, inverseJoinColumns = { @JoinColumn(name = "ROLES_ID") })
	private Set<Role> roles = new HashSet<Role>(0);

	
	private static String defaultLanguage = "EN"; 
	 
	/**
	 * Gets the user name.
	 * 
	 * @return the user name
	 */
	public String getUserName() {
		return userName;
	}

	/**
	 * Sets the user name.
	 * 
	 * @param name
	 *            the new user name
	 */
	public void setUserName(String name) {
		this.userName = name;
	}

	/**
	 * Sets the firstname.
	 * 
	 * @param firstname
	 *            the new firstname
	 */
	public void setFirstName(String firstname) {
		this.firstName = firstname;
	}

	/**
	 * Gets the firstname.
	 * 
	 * @return the firstname
	 */
	public String getFirstName() {
		if (lastName == null) return "";
		else return firstName;
	}

	/**
	 * Sets the lastname.
	 * 
	 * @param lastname
	 *            the new lastname
	 */
	public void setLastName(String lastname) {
		this.lastName = lastname;
	}

	/**
	 * Gets the lastname.
	 * 
	 * @return the lastname
	 */
	public String getLastName() {
		if (lastName == null) return "";
		else return lastName;
	}

	/**
	 * Sets the sapName.
	 * 
	 * @param sapName
	 *            the new sapName
	 */
	public void setSapName(String sapName) {
		this.sapName = sapName;
	}

	/**
	 * Gets the sapName.
	 * 
	 * @return the sapName
	 */
	public String getSapName() {
		if (sapName == null) return "";
		else return sapName;
	}

	/**
	 * Sets the sapName.
	 * 
	 * @param sapName
	 *            the new sapName
	 */
	public void setSapLanguage(String sapLanguage) {
		this.sapLanguage = sapLanguage;
	}

	/**
	 * Gets the sapName.
	 * 
	 * @return the sapName
	 */
	public String getSapLanguage() {
		if (this.sapLanguage == null) return getDefaultLanguage();
		if (this.sapLanguage.isEmpty()) return getDefaultLanguage();
		else return this.sapLanguage ;
	}
	
	/**
	 * Gets the password.
	 * 
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * Sets the password.
	 * 
	 * @param password
	 *            the new password
	 */
	public void setPassword(String password) {
		if (password != null)
			this.password = new BasicPasswordEncryptor().encryptPassword(password);
	}

	/**
	 * Sets the account non expired.
	 * 
	 * @param accountNonExpired
	 *            the new account non expired
	 */
	public void setAccountNonExpired(boolean accountNonExpired) {
		this.accountNonExpired = accountNonExpired;
	}

	/**
	 * Checks if is enabled.
	 * 
	 * @return true, if is enabled
	 */
	public boolean isEnabled() {
		return enabled;
	}

	/**
	 * Sets the enabled.
	 * 
	 * @param enabled
	 *            the new enabled
	 */
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	/**
	 * Authenticate.
	 * 
	 * @param password
	 *            the password
	 * @return true, if successful
	 */
	public boolean authenticate(String password) {
		return new BasicPasswordEncryptor().checkPassword(password, this.password);
	}

	/**
	 * Gets the email.
	 * 
	 * @return the email
	 */
	public String getEmail() {
		return emailAddress;
	}

	/**
	 * Sets the email.
	 * 
	 * @param email
	 *            the new email
	 */
	public void setEmail(String email) {
		this.emailAddress = email;
	}

	/**
	 * Gets the credentials none expired.
	 * 
	 * @return the credentials none expired
	 */
	public Date getCredentialsNoneExpired() {
		return credentialsNoneExpired;
	}

	/**
	 * Sets the credentials none expired.
	 * 
	 * @param credentialsNoneExpired
	 *            the new credentials none expired
	 */
	public void setCredentialsNoneExpired(Date credentialsNoneExpired) {
		this.credentialsNoneExpired = credentialsNoneExpired;
	}

	/**
	 * Checks if is credentials none expired.
	 * 
	 * @return true, if is credentials none expired
	 */
	public boolean isCredentialsNoneExpired() {

		if (this.credentialsNoneExpired == null)
			return true;

		if (this.credentialsNoneExpired.after(Calendar.getInstance().getTime()))
			return true;
		else
			return false;

	}

	/**
	 * Checks if is account non locked.
	 * 
	 * @return true, if is account non locked
	 */
	public boolean isAccountNonLocked() {
		return this.accountNonLocked;
	}

	/**
	 * Checks if is account non expired.
	 * 
	 * @return true, if is account non expired
	 */
	public boolean isAccountNonExpired() {
		return this.accountNonExpired;
	}

	/**
	 * Gets the account locked.
	 * 
	 * @return the account locked
	 */
	public boolean getAccountLocked() {
		return this.accountNonLocked;
	}

	/**
	 * Sets the account non locked.
	 * 
	 * @param accountLocked
	 *            the new account non locked
	 */
	public void setAccountNonLocked(boolean accountLocked) {
		this.accountNonLocked = accountLocked;
	}

	/**
	 * Sets the configurations.
	 * 
	 * @param configurations
	 *            the new configurations
	 */
	public void setConfigurations(String configurations) {
		this.configurations = configurations;
	}

	/**
	 * Gets the configurations.
	 * 
	 * @return the configurations
	 */
	public String getConfigurations() {
		return configurations;
	}

	/**
	 * Sets the roles.
	 * 
	 * @param roles
	 *            the new roles
	 */

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	/**
	 * Gets the roles.
	 * 
	 * @return the roles
	 */
	public Set<Role> getRoles() {
		return this.roles;
	}


	public static void setDefaultLanguage(String defaultLanguage) {
		User.defaultLanguage = defaultLanguage;
	}

	public static String getDefaultLanguage() {
		return defaultLanguage;
	}

	@Override
	public boolean equals(Object obj) {
		return ((User)obj).getUserName().equals(this.userName);
	}

}
